﻿#include "framework.h"
#include "Const.h"
#include "InputBox.h"
#include "LogonWindow.h"
#include "MainWindow.h"
#include "RegWindow.h"
#include "Resource.h"

// 函数声明
static void MainWindow_Delete(MainWindow*);
static void MainWindow_AddAllFriends(MainWindow*, const LogonResult*);
static void MainWindow_AddOneFriend(MainWindow*, LPCTSTR, int, BOOL);
static void MainWindow_ChangeState(MainWindow*, BOOL);
static void MainWindow_ClearChatWindow(MainWindow*);
static void MainWindow_DoModal(MainWindow*);
static ChatWindow* MainWindow_GetChatWindow(MainWindow*, LPCTSTR);
static void MainWindow_GetResultMessage(ResultCode, LPTSTR, int);
static void MainWindow_OnButtonAddFriendClicked(MainWindow*);
static void MainWindow_OnButtonLogoffClicked(MainWindow*);
static void MainWindow_OnButtonLogonClicked(MainWindow*);
static void MainWindow_OnButtonMChatClicked(MainWindow*);
static void MainWindow_OnButtonRegClicked(MainWindow*);
static void MainWindow_OnChatC2S(MainWindow*, const ChatInfo*);
static void MainWindow_OnChatS2C(MainWindow*, const ChatInfo*);
static void MainWindow_OnGetAddFriendRequest(MainWindow*, const AddFriendRequest*);
static void MainWindow_OnGetAddFriendResult(MainWindow*, const AddFriendResult*);
static void MainWindow_OnGetLogonResult(MainWindow*, const LogonResult*);
static void MainWindow_OnGetRegResult(MainWindow*, const RegResult*);
static void MainWindow_OnFriendLogoff(MainWindow*, const LogoffRequest*);
static void MainWindow_OnFriendLogon(MainWindow*, const FriendLogon*);
static void MainWindow_OnListFriendsDoubleClicked(MainWindow*, int);
static INT_PTR CALLBACK MainWindow_Proc(HWND, UINT, WPARAM, LPARAM);

/**
 * 创建主窗口。
 * @return 主窗口
 */
MainWindow* New_MainWindow() {
    DWORD style = 0;    // 控件风格
    HMODULE module = GetModuleHandle(NULL);
    HICON icon = LoadIcon(module, MAKEINTRESOURCE(IDI_LOGON));  // 工具栏按钮位图
    ICONINFO iconInfo = { 0 };
    BITMAP bmpInfo = { 0 };
    int iconFlag = 0;
    TBBUTTON tbButtons[] = {
        { 0, IDC_BUTTON_LOGON, TBSTATE_ENABLED, 0, 0, 0, 0 },
        { 1, IDC_BUTTON_REG, TBSTATE_ENABLED, 0, 0, 0, 0 },
        { 2, IDC_BUTTON_ADD_FRIEND, 0, 0, 0, 0, 0 },
        { 3, IDC_BUTTON_MCHAT, 0, 0, 0, 0, 0 }, 
        { 4, IDC_BUTTON_LOGOFF, 0, 0, 0, 0, 0 }
    };                                          // 工具栏按钮信息
    int buttonCount = sizeof(tbButtons) / sizeof(TBBUTTON);
    int parts[STATUS_BAR_PART_COUNT] = { 0 };   // 状态栏格宽度信息
    RECT toolBarRect = { 0 };                   // 工具栏的尺寸
    TCHAR text[STRING_BUF_LEN] = { 0 };         // 状态栏上的文字
    TCHAR format[STRING_BUF_LEN] = { 0 };
    LV_COLUMN column = { LVCF_WIDTH };          // 列信息
    MainWindow* mainWindow = (MainWindow*)calloc(1, sizeof(MainWindow));
    int i = 0;

    // 初始化数据
    mainWindow->mHandle = CreateDialog(NULL, MAKEINTRESOURCE(IDD_MAIN_WINDOW), NULL, MainWindow_Proc);
    SetWindowLongPtr(mainWindow->mHandle, GWLP_USERDATA, (LONG_PTR)mainWindow);
    style = WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT;
    mainWindow->mToolBar = CreateWindowEx(0, TOOLBARCLASSNAME, 0, style, 0, 0, 0, 0, mainWindow->mHandle, 0, NULL, 0);
    mainWindow->mListViewUsers = New_UserListView(IDC_LIST_VIEW_USERS, mainWindow->mHandle);
    style = WS_CHILD | WS_VISIBLE | CCS_BOTTOM;
    mainWindow->mStatusBar = CreateStatusWindow(style, NULL, mainWindow->mHandle, 0);

    // 初始化函数
    mainWindow->doModal = MainWindow_DoModal;

    // 设置工具栏
    GetIconInfo(icon, &iconInfo);
    GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmpInfo);
    iconFlag = bmpInfo.bmBitsPixel;
    if (iconInfo.hbmMask != NULL) {
        iconFlag |= ILC_MASK;
    }
    mainWindow->mImageList = ImageList_Create(bmpInfo.bmWidth, bmpInfo.bmHeight, iconFlag, buttonCount, 0);
    for (i = 0; i < buttonCount; i++) {
        icon = LoadIcon(module, MAKEINTRESOURCE(IDI_LOGON + i));
        ImageList_AddIcon(mainWindow->mImageList, icon);
    }
    SendMessage(mainWindow->mToolBar, TB_SETIMAGELIST, 0, (LPARAM)mainWindow->mImageList);  // 设置工具栏图标列表
    SendMessage(mainWindow->mToolBar, TB_ADDBUTTONS, buttonCount, (LPARAM)&tbButtons);      // 设置工具栏按钮
    SendMessage(mainWindow->mToolBar, TB_AUTOSIZE, 0, 0);                                   // 设置工具栏尺寸为不自动变化

    // 设置用户列表控件
    GetWindowRect(mainWindow->mToolBar, &toolBarRect);
    column.cx = toolBarRect.right - toolBarRect.left - GetSystemMetrics(SM_CXVSCROLL) - 3;
    ListView_InsertColumn(mainWindow->mListViewUsers->mHandle, 0, &column);                  // 用户列表控件添加一列

    // 设置状态栏
    GetWindowRect(mainWindow->mToolBar, &toolBarRect);
    parts[0] = (toolBarRect.right - toolBarRect.left) / 2;
    parts[1] = toolBarRect.right - toolBarRect.left;
    SendMessage(mainWindow->mStatusBar, SB_SETPARTS, STATUS_BAR_PART_COUNT, (LPARAM)parts); // 设置状态栏的格的宽度
    LoadString(NULL, IDS_STATUS_LOGOFF, text, STRING_BUF_LEN);
    SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 0, (LPARAM)text);                       // 设置状态栏第1格的文字
    LoadString(NULL, IDS_FRIEND_COUNT, format, STRING_BUF_LEN);
    _stprintf_s(text, STRING_BUF_LEN, format, 0);
    SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 1, (LPARAM)text);                       // 设置状态栏第2格的文字

    // 创建客户端
    mainWindow->mClient = New_Client(mainWindow->mHandle);
    if (mainWindow->mClient == NULL) {
        MainWindow_GetResultMessage(NETWORK_ERROR, text, STRING_BUF_LEN);
        MessageBox(mainWindow->mHandle, text, _T(" "), MB_ICONERROR);
        exit(0);
    }

    return mainWindow;
}

/**
 * 删除主窗口。
 * @param mainWindow    主窗口
 */
static void MainWindow_Delete(MainWindow* mainWindow) {
    // 清除所有聊天窗口
    MainWindow_ClearChatWindow(mainWindow);

    // 删除客户端
    mainWindow->mClient->deleteSelf(mainWindow->mClient);

    // 销毁控件
    mainWindow->mListViewUsers->deleteSelf(mainWindow->mListViewUsers);
    DeleteObject(mainWindow->mImageList);
    DestroyWindow(mainWindow->mStatusBar);
    DestroyWindow(mainWindow->mToolBar);

    // 销毁自身
    DestroyWindow(mainWindow->mHandle);

    // 释放内存
    free(mainWindow);
}

/**
 * 添加所有好友到好友列表控件中。
 * @param mainWindow    主窗口
 * @param result        登录结果
 */
static void MainWindow_AddAllFriends(MainWindow* mainWindow, const LogonResult* result) {
    TCHAR text[STRING_BUF_LEN] = { 0 };
    TCHAR format[STRING_BUF_LEN] = { 0 };
    int i = 0;

    for (i = 0; i < result->mFriendCount; i++) {
        MainWindow_AddOneFriend(mainWindow, result->mFriends[i].mUsername, result->mFriends[i].mIconIndex, result->mFriendsOnline[i]);
    }

    LoadString(NULL, IDS_FRIEND_COUNT, format, STRING_BUF_LEN);
    _stprintf_s(text, STRING_BUF_LEN, format, result->mFriendCount);
    SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 1, (LPARAM)text);
}

/**
 * 添加一个好友到好友列表控件中。
 * @param mainWindow    主窗口
 * @param friendName    好友名
 * @param iconIndex     好友头像索引
 * @param isOnline      好友在线则为 TRUE，否则为 FALSE
 */
static void MainWindow_AddOneFriend(MainWindow* mainWindow, LPCTSTR friendName, int iconIndex, BOOL isOnline) {
    if (iconIndex < 0) {
        return;
    }
    mainWindow->mListViewUsers->addItem(mainWindow->mListViewUsers, friendName, iconIndex, isOnline);
}

/**
 * 改变界面状态。
 * @param mainWindow    主窗口
 * @param isLogon       已登录则为 true，否则为 false
 */
static void MainWindow_ChangeState(MainWindow* mainWindow, BOOL isLogon) {
    TCHAR text[STRING_BUF_LEN] = { 0 };
    TCHAR format[STRING_BUF_LEN] = { 0 };

    SendMessage(mainWindow->mToolBar, TB_ENABLEBUTTON, IDC_BUTTON_LOGON, !isLogon);
    SendMessage(mainWindow->mToolBar, TB_ENABLEBUTTON, IDC_BUTTON_REG, !isLogon);
    SendMessage(mainWindow->mToolBar, TB_ENABLEBUTTON, IDC_BUTTON_ADD_FRIEND, isLogon);
    SendMessage(mainWindow->mToolBar, TB_ENABLEBUTTON, IDC_BUTTON_MCHAT, isLogon);
    SendMessage(mainWindow->mToolBar, TB_ENABLEBUTTON, IDC_BUTTON_LOGOFF, isLogon);

    if (isLogon) {
        LoadString(NULL, IDS_STATUS_LOGON, text, STRING_BUF_LEN);
        SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 0, (LPARAM)text);
    } else {
        LoadString(NULL, IDS_STATUS_LOGOFF, text, STRING_BUF_LEN);
        SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 0, (LPARAM)text);
    }
    LoadString(NULL, IDS_FRIEND_COUNT, format, STRING_BUF_LEN);
    _stprintf_s(text, STRING_BUF_LEN, format, 0);
    SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 1, (LPARAM)text);
}

/**
 * 清除所有聊天窗口。
 * @param mainWindow    主窗口
 */
static void MainWindow_ClearChatWindow(MainWindow* mainWindow) {
    ChatWindow* chatWindow = mainWindow->mHead;
    while (chatWindow != NULL) {
        mainWindow->mHead = mainWindow->mHead->mNext;
        chatWindow->deleteSelf(chatWindow);
        chatWindow = mainWindow->mHead;
    }
}

/**
 * 以模态显示窗口。
 * @param mainWindow    主窗口
 */
static void MainWindow_DoModal(MainWindow* mainWindow) {
    MSG msg = { 0 };

    // 显示窗口
    ShowWindow(mainWindow->mHandle, SW_SHOW);

    // 窗口事件循环
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

/**
 * 获取指定好友名对应的聊天窗口。
 * @param mainWindow    主窗口
 * @param friendName    好友名
 * @return 好友名对应的聊天窗口
 */
static ChatWindow* MainWindow_GetChatWindow(MainWindow* mainWindow, LPCTSTR friendName) {
    // 查找用户名对应的聊天窗口
    ChatWindow* chatWindow = mainWindow->mHead;
    while (chatWindow != NULL) {
        if (_tcscmp(friendName, chatWindow->mFriendName) == 0) {
            break;
        }
        chatWindow = chatWindow->mNext;
    }

    // 未找到，则新建一个
    if (chatWindow == NULL) {
        chatWindow = New_ChatWindow(mainWindow->mHandle, friendName);
        if (mainWindow->mHead == NULL) {
            mainWindow->mHead = chatWindow;
        } else if (mainWindow->mCauda == NULL) {
            mainWindow->mCauda = chatWindow;
            mainWindow->mHead->mNext = mainWindow->mCauda;
        } else {
            mainWindow->mCauda->mNext = chatWindow;
            mainWindow->mCauda = chatWindow;
        }
    }

    return chatWindow;
}

/**
 * 获取结果信息。
 * @param resultCode    结果码
 * @param text          返回的结果信息
 * @param textLen       结果信息的长度
 */
static void MainWindow_GetResultMessage(ResultCode resultCode, LPTSTR text, int textLen) {
    switch (resultCode) {
        case ADD_FRIEND_ALLOW:
            LoadString(NULL, IDS_ADD_FRIEND_ALLOW, text, textLen);
            break;
        case ADD_FRIEND_NOT_ALLOW:
            LoadString(NULL, IDS_ADD_FRIEND_NOT_ALLOW, text, textLen);
            break;
        case ALREADY_BE_FRIENDS:
            LoadString(NULL, IDS_ALREADY_BE_FRIENDS, text, textLen);
            break;
        case FRIEND_NAME_EQUAL_SELF_NAME:
            LoadString(NULL, IDS_FRIEND_NAME_EQUAL_SELF_NAME, text, textLen);
            break;
        case NETWORK_ERROR:
            LoadString(NULL, IDS_NETWORK_ERROR, text, textLen);
            break;
        case PASSWORD_WRONG:
            LoadString(NULL, IDS_PASSWORD_WRONG, text, textLen);
            break;
        case REG_SUCCEEDED:
            LoadString(NULL, IDS_REG_SUCCEEDED, text, textLen);
            break;
        case TOO_MANY_FRIENDS:
            LoadString(NULL, IDS_TOO_MANY_FRIENDS, text, textLen);
            break;
        case USER_ALREADY_LOGON:
            LoadString(NULL, IDS_USER_ALREADY_LOGON, text, textLen);
            break;
        case USER_EXISTS:
            LoadString(NULL, IDS_USER_EXISTS, text, textLen);
            break;
        case USER_NOT_FOUND:
            LoadString(NULL, IDS_USER_NOT_FOUND, text, textLen);
            break;
    }
}

/**
 * "添加好友"按钮的单击响应函数。
 * @param mainWindow    主窗口
 */
static void MainWindow_OnButtonAddFriendClicked(MainWindow* mainWindow) {
    // 显示输入窗口，让用户输入好友名
    ResultCode resultCode = SUCCEEDED;
    InputBox* inputBox = NULL;
    TCHAR tipText[STRING_BUF_LEN] = { 0 };

    LoadString(NULL, IDS_PLEASE_INPUT_USERNAME, tipText, STRING_BUF_LEN);
    inputBox = New_InputBox_String(MAX_USERNAME_LEN, mainWindow->mHandle, tipText);
    if (inputBox->doModal(inputBox) == IDCANCEL) {
        free(inputBox);
        return;
    }

    // 执行添加好友
    resultCode = mainWindow->mClient->addFriend(mainWindow->mClient, inputBox->mStringValue);
    if (resultCode != SUCCEEDED) {
        MainWindow_GetResultMessage(resultCode, tipText, STRING_BUF_LEN);
        MessageBox(mainWindow->mHandle, tipText, _T(" "), MB_ICONWARNING);
    }
    free(inputBox);
}

/**
 * "离线"按钮的单击响应函数。
 * @param mainWindow    主窗口
 */
static void MainWindow_OnButtonLogoffClicked(MainWindow* mainWindow) {
    // 设置各种控件的状态
    MainWindow_ChangeState(mainWindow, FALSE);

    // 清空各种列表
    ListView_DeleteAllItems(mainWindow->mListViewUsers->mHandle);
    MainWindow_ClearChatWindow(mainWindow);

    // 发送离线请求
    mainWindow->mClient->logoff(mainWindow->mClient);
}

/**
 * "登录"按钮的单击响应函数。
 * @param mainWindow    主窗口
 */
static void MainWindow_OnButtonLogonClicked(MainWindow* mainWindow) {
    // 显示登录窗口
    LogonWindow* logonWindow = New_LogonWindow(mainWindow->mHandle);
    INT_PTR clickedButton = logonWindow->doModal(logonWindow);
    if (clickedButton == IDOK) {
        // 登录
        mainWindow->mClient->logon(mainWindow->mClient, logonWindow->mUsername, logonWindow->mPassword);
    }
    logonWindow->deleteSelf(logonWindow);
}

/**
 * "群发消息"按钮的单击响应函数。
 * @param mainWindow    主窗口
 */
static void MainWindow_OnButtonMChatClicked(MainWindow* mainWindow) {
    ChatWindow* chatWindow = MainWindow_GetChatWindow(mainWindow, MULTI_CHAT);
    ShowWindow(chatWindow->mHandle, SW_SHOW);
}

/**
 * "注册"按钮的单击响应函数。
 * @param mainWindow    主窗口
 */
static void MainWindow_OnButtonRegClicked(MainWindow* mainWindow) {
    // 显示注册窗口
    RegWindow* regWindow = New_RegWindow(mainWindow->mHandle);
    INT_PTR nResult = regWindow->doModal(regWindow);
    if (nResult == IDOK) {
        // 注册
        mainWindow->mClient->reg(mainWindow->mClient, regWindow->mUsername, regWindow->mPassword, regWindow->mIconIndex);
    }
    regWindow->deleteSelf(regWindow);
}

/**
 * 聊天事件的响应函数（客户端到服务器）。
 * @param mainWindow    主窗口
 * @param chatInfo      聊天信息
 */
static void MainWindow_OnChatC2S(MainWindow* mainWindow, const ChatInfo* chatInfo) {
    mainWindow->mClient->chat(mainWindow->mClient, chatInfo);
}

/**
 * 聊天事件的响应函数（服务器到客户端）。
 * @param mainWindow    主窗口
 * @param chatInfo      聊天信息
 */
static void MainWindow_OnChatS2C(MainWindow* mainWindow, const ChatInfo* chatInfo) {
    ChatWindow* chatWindow = NULL;
    if (_tcscmp(chatInfo->mDstUsername, MULTI_CHAT) == 0) {
        chatWindow = MainWindow_GetChatWindow(mainWindow, MULTI_CHAT);
    } else {
        chatWindow = MainWindow_GetChatWindow(mainWindow, chatInfo->mSrcUsername);
    }
    chatWindow->setContent(chatWindow, chatInfo);
    ShowWindow(chatWindow->mHandle, SW_SHOW);
}

/**
 * 好友离线事件的响应函数。
 * @param mainWindow    主窗口
 * @param friendLogoff  离线请求
 */
static void MainWindow_OnFriendLogoff(MainWindow* mainWindow, const LogoffRequest* friendLogoff) {
    mainWindow->mListViewUsers->changeItemColor(mainWindow->mListViewUsers, friendLogoff->mUsername, FALSE);
}

/**
 * 好友登录事件的响应函数。
 * @param mainWindow    主窗口
 * @param friendLogon   好友登录信息
 */
static void MainWindow_OnFriendLogon(MainWindow* mainWindow, const FriendLogon* friendLogon) {
    mainWindow->mListViewUsers->changeItemColor(mainWindow->mListViewUsers, friendLogon->mUsername, TRUE);
}

/**
 * 得到添加好友请求事件的响应函数。
 * @param mainWindow    主窗口
 * @param request       添加好友请求
 */
static void MainWindow_OnGetAddFriendRequest(MainWindow* mainWindow, const AddFriendRequest* request) {
    TCHAR message[STRING_BUF_LEN] = { 0 };
    TCHAR text[STRING_BUF_LEN] = { 0 };
    INT_PTR clickedButton = 0;
    BOOL allow = FALSE;
    TCHAR format[STRING_BUF_LEN] = { 0 };

    _tcscpy_s(message, STRING_BUF_LEN, request->mSrcUsername);
    LoadString(NULL, IDS_CONFIRM_ADD_FRIEND, text, STRING_BUF_LEN);
    _tcscat_s(message, STRING_BUF_LEN, text);
    clickedButton = MessageBox(mainWindow->mHandle, message, _T(" "), MB_ICONQUESTION | MB_YESNO);
    allow = clickedButton == IDYES;
    mainWindow->mClient->allowAddFriend(mainWindow->mClient, allow, request);
    if (allow) {
        MainWindow_AddOneFriend(mainWindow, request->mSrcUsername, request->mSrcIconIndex, TRUE);
        LoadString(NULL, IDS_FRIEND_COUNT, format, STRING_BUF_LEN);
        _stprintf_s(text, STRING_BUF_LEN, format, mainWindow->mClient->mFriendCount);
        SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 1, (LPARAM)text);
    }
}

/**
 * 得到添加好友结果事件的响应函数。
 * @param mainWindow    主窗口
 * @param result        添加好友结果
 */
static void MainWindow_OnGetAddFriendResult(MainWindow* mainWindow, const AddFriendResult* result) {
    TCHAR text[STRING_BUF_LEN] = { 0 };
    TCHAR format[STRING_BUF_LEN] = { 0 };
    TCHAR message[STRING_BUF_LEN] = { 0 };

    if (result->mResultCode == ADD_FRIEND_ALLOW) {
        MainWindow_AddOneFriend(mainWindow, result->mDstUsername, result->mDstIconIndex, TRUE);
        LoadString(NULL, IDS_FRIEND_COUNT, format, STRING_BUF_LEN);
        _stprintf_s(text, STRING_BUF_LEN, format, mainWindow->mClient->mFriendCount);
        SendMessage(mainWindow->mStatusBar, SB_SETTEXT, 1, (LPARAM)text);

        MainWindow_GetResultMessage(result->mResultCode, format, STRING_BUF_LEN);
        _stprintf_s(message, STRING_BUF_LEN, format, result->mDstUsername);
        MessageBox(mainWindow->mHandle, message, _T(" "), MB_ICONINFORMATION);
    } else if (result->mResultCode == ALREADY_BE_FRIENDS ||
        result->mResultCode == ADD_FRIEND_NOT_ALLOW ||
        result->mResultCode == USER_NOT_FOUND) {
        _tcscpy_s(text, STRING_BUF_LEN, result->mDstUsername);
        MainWindow_GetResultMessage(result->mResultCode, message, STRING_BUF_LEN);
        _tcscat_s(text, STRING_BUF_LEN, message);
        MessageBox(mainWindow->mHandle, text, _T(" "), MB_ICONWARNING);
    }
}

/**
 * 得到登录结果事件的响应函数。
 * @param mainWindow    主窗口
 * @param result        登录结果
 */
static void MainWindow_OnGetLogonResult(MainWindow* mainWindow, const LogonResult* result) {
    TCHAR message[STRING_BUF_LEN] = { 0 };

    if (result->mResultCode == LOGON_SUCCEEDED) {
        MainWindow_ChangeState(mainWindow, TRUE);
        MainWindow_AddAllFriends(mainWindow, result);
    } else {
        MainWindow_GetResultMessage(result->mResultCode, message, STRING_BUF_LEN);
        MessageBox(mainWindow->mHandle, message, _T(" "), MB_ICONERROR);
    }
}

/**
 * 得到注册结果事件的响应函数。
 * @param mainWindow    主窗口
 * @param result        注册结果
 */
static void MainWindow_OnGetRegResult(MainWindow* mainWindow, const RegResult* result) {
    TCHAR message[STRING_BUF_LEN] = { 0 };

    MainWindow_GetResultMessage(result->mResultCode, message, STRING_BUF_LEN);
    if (result->mResultCode == REG_SUCCEEDED) {
        MainWindow_ChangeState(mainWindow, TRUE);
        MessageBox(mainWindow->mHandle, message, _T(" "), MB_ICONINFORMATION);
    } else {
        MessageBox(mainWindow->mHandle, message, _T(" "), MB_ICONERROR);
    }
}

/**
 * 双击好友列表控件的响应函数。
 * @param mainWindow    主窗口
 * @param item          被双击的表项的索引
 */
static void MainWindow_OnListFriendsDoubleClicked(MainWindow* mainWindow, int item) {
    ChatWindow* chatWindow = NULL;
    TCHAR friendName[USERNAME_BUF_LEN] = { 0 };
    ListView_GetItemText(mainWindow->mListViewUsers->mHandle, item, 0, friendName, USERNAME_BUF_LEN);
    if (friendName[0] == '\0') {
        return;
    }
    chatWindow = MainWindow_GetChatWindow(mainWindow, friendName);
    ShowWindow(chatWindow->mHandle, SW_SHOW);
}

/**
 * 窗口过程函数。
 * @param window    窗口
 * @param message   事件标识
 * @param wParam    事件相关信息1
 * @param lParam    事件相关信息2
 * @return 事件在此被处理则返回 TRUE，否则返回 FALSE
 */
static INT_PTR CALLBACK MainWindow_Proc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) {
    MainWindow* mainWindow = (MainWindow*)GetWindowLongPtr(window, GWLP_USERDATA);
    LPNMHDR nmhdr = NULL;
    LPTOOLTIPTEXT tooltipText = NULL;
    WORD id = LOWORD(wParam);

    switch (message) {
        case WM_CLOSE:
            MainWindow_Delete(mainWindow);
            break;
        case WM_COMMAND:
            switch (id) {
                case IDC_BUTTON_ADD_FRIEND:
                    MainWindow_OnButtonAddFriendClicked(mainWindow);
                    break;
                case IDC_BUTTON_LOGOFF:
                    MainWindow_OnButtonLogoffClicked(mainWindow);
                    break;
                case IDC_BUTTON_LOGON:
                    MainWindow_OnButtonLogonClicked(mainWindow);
                    break;
                case IDC_BUTTON_MCHAT:
                    MainWindow_OnButtonMChatClicked(mainWindow);
                    break;
                case IDC_BUTTON_REG:
                    MainWindow_OnButtonRegClicked(mainWindow);
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_NOTIFY:
            nmhdr = (LPNMHDR)lParam;
            if (nmhdr->code == TTN_GETDISPINFO) {
                tooltipText = (LPTOOLTIPTEXT)lParam;
                switch (tooltipText->hdr.idFrom) {
                case IDC_BUTTON_LOGON:
                    LoadString(NULL, IDS_LOGON, tooltipText->szText, STRING_BUF_LEN);
                    break;
                case IDC_BUTTON_REG:
                    LoadString(NULL, IDS_REG, tooltipText->szText, STRING_BUF_LEN);
                    break;
                case IDC_BUTTON_ADD_FRIEND:
                    LoadString(NULL, IDS_ADD_FRIEND, tooltipText->szText, STRING_BUF_LEN);
                    break;
                case IDC_BUTTON_MCHAT:
                    LoadString(NULL, IDS_MCHAT, tooltipText->szText, STRING_BUF_LEN);
                    break;
                case IDC_BUTTON_LOGOFF:
                    LoadString(NULL, IDS_LOGOFF, tooltipText->szText, STRING_BUF_LEN);
                    break;
                }
            } else if (nmhdr->code == NM_DBLCLK) {
                MainWindow_OnListFriendsDoubleClicked(mainWindow, ((LPNMITEMACTIVATE)nmhdr)->iItem);
            }
            break;
        case UM_CHAT_C2S:
            MainWindow_OnChatC2S(mainWindow, (ChatInfo*)wParam);
            break;
        case UM_CHAT_S2C:
            MainWindow_OnChatS2C(mainWindow, (ChatInfo*)wParam);
            break;
        case UM_FRIEND_LOGOFF:
            MainWindow_OnFriendLogoff(mainWindow, (LogoffRequest*)wParam);
            break;
        case UM_FRIEND_LOGON:
            MainWindow_OnFriendLogon(mainWindow, (FriendLogon*)wParam);
            break;
        case UM_GET_ADD_FRIEND_REQUEST:
            MainWindow_OnGetAddFriendRequest(mainWindow, (AddFriendRequest*)wParam);
            break;
        case UM_GET_ADD_FRIEND_RESULT:
            MainWindow_OnGetAddFriendResult(mainWindow, (AddFriendResult*)wParam);
            break;
        case UM_GET_LOGON_RESULT:
            MainWindow_OnGetLogonResult(mainWindow, (LogonResult*)wParam);
            break;
        case UM_GET_REG_RESULT:
            MainWindow_OnGetRegResult(mainWindow, (RegResult*)wParam);
            break;
    }
    return FALSE;
}
